<template>
  <div>
    <div class="row justify-end">
      <q-btn label="新增" icon="add" flat color="red" @click="showAdd" />
    </div>
    <q-list separator>
      <q-item v-for="(row, idx) in tableRows" :key="idx">
        <q-item-section>
          <q-item-label v-for="(col, idx2) in columns" :key="idx2" :class="col.classes">
            <div v-if="col.type === 'text'">{{ row[col.field] }}</div>
            <div v-else-if="col.type === 'toggle'">{{ row[col.field] ? col.label : '' }}</div>
          </q-item-label>
        </q-item-section>
        <q-item-section avatar>
          <q-btn icon="border_color" flat dense color="grey-6" @click="showEdit(row)" />
        </q-item-section>
      </q-item>
    </q-list>

    <q-dialog v-model="dialog" full-width position="bottom">
      <q-card flat class="full-width">
        <q-card-actions class="flex justify-between">
          <q-btn color="grey-10" flat v-close-popup>取消</q-btn>
          <div>
            <q-btn color="grey-8" flat @click="deleteRow">删除</q-btn>
            <q-btn color="negative" @click="confirm">保存</q-btn>
          </div>
        </q-card-actions>

        <q-separator />

        <q-card-section class="q-gutter-y-md">
          <div v-for="(col, idx) in columns" :key="idx">
            <q-input v-if="col.type === 'text'" filled v-model="dataRow[col.field]" :label="col.label" />
            <q-toggle v-if="col.type === 'toggle'" v-model="dataRow[col.field]" :label="col.label" />
          </div>
        </q-card-section>
      </q-card>
    </q-dialog>
  </div>
</template>

<script>
import { defineComponent } from 'vue';
import { uid } from 'quasar';

export default defineComponent({
  name: 'ListTable',
  props: {
    rows: { type: Array, default: () => [] },
    columns: { type: Array, default: () => [] }
  },
  emits: ['update:rows'],
  data () {
    return {
      dialog: false,
      dataRow: {},
      mode: ''
    };
  },
  methods: {
    showAdd () { // 新增
      const row = { _uid: uid() };
      for (const col of this.columns) {
        if (col.type === 'text') {
          row[col.field] = '';
        } else if (col.type === 'toggle') {
          row[col.field] = false;
        }
      }
      this.dataRow = row;
      this.mode = 'add';
      this.dialog = true;
    },
    showEdit (row) { // 修改
      this.dataRow = { ...row };
      this.mode = 'edit';
      this.dialog = true;
    },
    confirm () { // 确认
      // 检查唯一性
      const uniqueCols = this.columns.filter(v => v.uniqueValue !== undefined);
      if (uniqueCols.length > 0) {
        for (const col of uniqueCols) {
          if (this.dataRow[col.field] === col.uniqueValue) { // 若当前编辑数据与唯一值相同，修改其它行数据，保持唯一性
            for (const row of this.tableRows) {
              if (row._uid !== this.dataRow._uid) {
                row[col.field] = col.normalValue; // 其它行设置成普通值
              }
            }
          }
        }
      }

      if (this.mode === 'add') {
        this.tableRows.push(this.dataRow);
      } else if (this.mode === 'edit') {
        const row = this.tableRows.find(v => v._uid === this.dataRow._uid);
        for (const [key, value] of Object.entries(this.dataRow)) {
          row[key] = value;
        }
      }
      this.$emit('update:rows', this.tableRows);
      this.dialog = false;
    },
    deleteRow () { // 删除
      const idx = this.tableRows.find(v => v._uid === this.dataRow._uid);
      this.tableRows.splice(idx, 1);
      this.$emit('update:rows', this.tableRows);
      this.dialog = false;
    }
  },
  computed: {
    tableRows () {
      if (this.rows) {
        return this.rows.map(v => ({
          _uid: uid(),
          ...v
        }));
      } else {
        return [];
      }
    }
  }
});
</script>
